package klass.parse.domain;

import klass.parse.domain.attribute.Attribute;

import java.util.List;

public class MethodInfo {

    private static final short ACC_PUBLIC = 0x0001;
    private static final short ACC_PRIVATE = 0x0002;
    private static final short ACC_PROTECTED = 0x0004;
    private static final short ACC_STATIC = 0x0008;
    private static final short ACC_FINAL = 0x0010;
    private static final short ACC_SYNCHRONIZED = 0x0020;
    private static final short ACC_BRIDGE = 0x0040;
    private static final short ACC_NATIVE = 0x0100;
    private static final short ACC_ABSTRACT = 0x0400;
    private static final short ACC_STRICTFP = 0x0800;
    private static final short ACC_SYNTHETIC = 0x1000;

    private String name;
    private String descriptor;
    private short flags;
    private List<Attribute> attributes;


    public boolean isPublic() {
        return is(ACC_PUBLIC);
    }

    public boolean isPrivate() {
        return is(ACC_PRIVATE);
    }

    public boolean isProtected() {
        return is(ACC_PROTECTED);
    }

    public boolean isStatic() {
        return is(ACC_STATIC);
    }

    public boolean isFinal() {
        return is(ACC_FINAL);
    }

    public boolean isSynchronized() {
        return is(ACC_SYNCHRONIZED);
    }

    public boolean isBridge() {
        return is(ACC_BRIDGE);
    }

    public boolean isNative() {
        return is(ACC_NATIVE);
    }

    public boolean isAbstract() {
        return is(ACC_ABSTRACT);
    }

    public boolean isStrictfp() {
        return is(ACC_STRICTFP);
    }

    public boolean isSynthenic() {
        return is(ACC_SYNTHETIC);
    }

    private boolean is(short check) {
        return check == (check & flags);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescriptor() {
        return descriptor;
    }

    public void setDescriptor(String descriptor) {
        this.descriptor = descriptor;
    }

    public short getFlags() {
        return flags;
    }

    public void setFlags(short flags) {
        this.flags = flags;
    }

    public List<Attribute> getAttributes() {
        return attributes;
    }

    public void setAttributes(List<Attribute> attributes) {
        this.attributes = attributes;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        if (isPublic()) builder.append(" public");
        if (isPrivate()) builder.append(" private");
        if (isProtected()) builder.append(" protected");
        if (isStatic()) builder.append(" static");
        if (isFinal()) builder.append(" final");
        if (isSynchronized()) builder.append(" synchronized");
        if (isNative()) builder.append(" native");
        if (isAbstract()) builder.append(" abstract");
        if (isStrictfp()) builder.append(" strictfp");
        builder.append(" ").append(descriptor);
        builder.append(" ").append(name);
        return builder.toString();
    }
}
